package cn.mesmile.emqtt.controller;

import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.PostConstruct;
import java.util.HashMap;

/**
 * @author zb
 * @date 2021/7/11 14:00
 * @Description
 */
@Slf4j
@RequestMapping("/mqtt")
@RestController
public class AuthController {

    private HashMap<String,String> users;

    private HashMap<String,String> clientIds;

    @PostConstruct
    public void init(){
        users = new HashMap<>(16);
        users.put("user", "123456");
        users.put("emq", "123456");
        clientIds = new HashMap<>(16);
        clientIds.put("emq_client", "123456");
        clientIds.put("emq_client_test", "123456");
    }

    /**
     *  返回参数：
     *      认证失败：API返同4xx状态码
     *      认证成功：API返回 200状态码
     *      忽略认证：API汲同200状态码且消息体ignore
     *
     *     认证api
     * @param clientid
     * @param username
     * @param password
     * @return
     */
    @PostMapping("/auth")
    public ResponseEntity auth(@RequestParam("clientid")String clientid, @RequestParam("username")String username,
                               @RequestParam("password")String password
                     ){
        log.info(">>>>>>>>>>> emqx 开始认证：clientid:{}，username:{}，password:{}", clientid, username, password);
        if (StrUtil.isEmpty(password)){
            return new ResponseEntity<Object>(HttpStatus.UNAUTHORIZED);
        }
        if (StrUtil.isNotEmpty(username)) {
            String pwd = users.get(username);
            if (pwd.equals(password)) {
                return new ResponseEntity(HttpStatus.OK);
            }
        }
        if (StrUtil.isNotEmpty(clientid)) {
            String pwd = clientIds.get(clientid);
            if (pwd.equals(password)) {
                return new ResponseEntity(HttpStatus.OK);
            }
        }
        return new ResponseEntity(HttpStatus.UNAUTHORIZED);
    }

    /**
     *  查询是否为 超级用户 ，超级用户不受 ACL 限制
     * @param clientid
     * @param username
     * @return
     */
    @PostMapping("/superuser")
    public ResponseEntity superUser(@RequestParam("clientid")String clientid,@RequestParam("username")String username){
        log.info(">>>>>>>>>> 查询用户是否为superuser: clientid:{} , username:{}", clientid, username);
        if ("admin".equals(clientid) || "admin".equals(username)){
            // 超级用户
            log.info(">>>>>>>>>> 用户为superuser: clientid:{} , username:{}", clientid, username);
            return new ResponseEntity(HttpStatus.OK);
        }else {
            // 非超级用户
            log.info(">>>>>>>>>> 用户非superuser: clientid:{} , username:{}", clientid, username);
            return new ResponseEntity(HttpStatus.BAD_REQUEST);
        }
    }

    /**
     *  查询用户或客户端 ACL 权限信息
     * @param access  1 代表订阅，2 代表发布
     * @param username
     * @param clientid
     * @param ipaddr
     * @param topic
     * @param mountpoint
     * @return
     */
    @PostMapping("/acl")
    public ResponseEntity acl(
                        @RequestParam("access")int access,
                        @RequestParam("username")String username,
                        @RequestParam("clientid")String clientid,
                        @RequestParam("ipaddr")String ipaddr,
                        @RequestParam("topic")String topic,
                        @RequestParam("mountpoint")String mountpoint
                                ){
        log.info(">>>>>>>>>> 查询acl信息：access:{}, username:{}, clientid:{}, ipaddr:{},topic:{},mountpoint:{}",
                    access == 1 ? "订阅":"发布", username, clientid, ipaddr, topic, mountpoint
                );
        if(username.equals("emq") && topic.equals("testtopic/#") && access == 1){
            log.info(">>>>>>>>>> 有订阅消息权限：access:{}, username:{}, clientid:{}, ipaddr:{},topic:{},mountpoint:{}",
                    access == 1 ? "订阅":"发布", username, clientid, ipaddr, topic, mountpoint);
            return new ResponseEntity(HttpStatus.OK);
        }
        if(username.equals("emq2") && topic.equals("testtopic/123") && access == 2){
            log.info(">>>>>>>>>> 有发布消息权限：access:{}, username:{}, clientid:{}, ipaddr:{},topic:{},mountpoint:{}",
                    access == 1 ? "订阅":"发布", username, clientid, ipaddr, topic, mountpoint);
            return new ResponseEntity(HttpStatus.OK);
        }
        log.info(">>>>>>>>>> 无权限发布和订阅消息：access:{}, username:{}, clientid:{}, ipaddr:{},topic:{},mountpoint:{}",
                access == 1 ? "订阅":"发布", username, clientid, ipaddr, topic, mountpoint);
        return new ResponseEntity(HttpStatus.BAD_REQUEST);
    }
}
